//
// Created by lenovo on 2024/7/2.
//

#ifndef TEYVATSURVIVAL_GAME_Msg_Message_H
#define TEYVATSURVIVAL_GAME_Msg_Message_H
#include "../Obj/GameObj.h"
#include <set>
#include <vector>
using namespace std ;
namespace Game::Msg{
    using namespace Game::Obj;


    /**
     * @msg
     * Obj向总控制器传输的Evnet
     * 如销毁等等
     */
    interface Message{
    public:
        enum class Type{
            Destroy ,
            Collision
        };
        virtual Type getType() = 0 ;
        virtual GameObj* getSender() = 0 ;
    };

    class MsgBus {
    public:
        static MsgBus& getInstance() {
            static MsgBus instance;
            return instance;
        }

        std::map<Message::Type, std::vector<Message*>> eventSet;

        void post(Message* event) {
            eventSet[event->getType()].push_back(event);
        }

        std::vector<Message*>& getMsgs(Message::Type type) {
            return eventSet[type];
        }

        void removeMsg(Message* msg) {
            auto& msgs = eventSet[msg->getType()];
            msgs.erase(std::remove(msgs.begin(), msgs.end(), msg), msgs.end());
        }

        void removeByObj(GameObj* obj) {
            for (auto& [type, events] : eventSet) {
                auto it = std::remove_if(events.begin(), events.end(),
                                         [obj](Message* event) { return event->getSender() == obj; });
                events.erase(it, events.end());
            }
        }


    protected:
        MsgBus() = default;
        MsgBus(const MsgBus&) = delete;
        MsgBus& operator=(const MsgBus&) = delete;

    };


    class DestroyMsg : public Message{
    public:
        DestroyMsg(GameObj* Obj) : obj(Obj) {}
        Type getType() override {return Type::Destroy ;}
        GameObj* getSender () override {return obj ;}

        GameObj* obj ;
    };

    class CollisionMsg : public Message{
    public:
        CollisionMsg() = default;
        CollisionMsg(GameObj* collider1 , GameObj* collider2){
            recordColliders(collider1,collider2);
        }
        Type getType() override{ return Message::Type::Collision ;}
        GameObj* getSender () override {return obj;}
        auto getCollidePair() {return collidePair;}
        void recordColliders (GameObj* collider1 , GameObj* collider2){
            collidePair.first = collider1;
            collidePair.second = collider2;
        }


        GameObj* obj {nullptr};
        pair<GameObj*,GameObj*> collidePair = pair<GameObj*,GameObj*>();
    };

}
#endif //TEYVATSURVIVAL_GAME_EVENT_EVENT_H
